package cn.stylefeng.guns.modular.service.impl;

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.log.Log;
import cn.stylefeng.guns.core.enums.CommonStatusEnum;
import cn.stylefeng.guns.core.pojo.login.SysLoginUser;
import cn.stylefeng.guns.modular.service.MiniAppUserService;
import cn.stylefeng.guns.sys.core.cache.UserCache;
import cn.stylefeng.guns.sys.core.enums.AdminTypeEnum;
import cn.stylefeng.guns.sys.core.enums.SexEnum;
import cn.stylefeng.guns.sys.core.jwt.JwtPayLoad;
import cn.stylefeng.guns.sys.core.jwt.JwtTokenUtil;
import cn.stylefeng.guns.sys.modular.auth.service.AuthService;
import cn.stylefeng.guns.sys.modular.auth.service.impl.AuthServiceImpl;
import cn.stylefeng.guns.sys.modular.emp.param.SysEmpParam;
import cn.stylefeng.guns.sys.modular.emp.service.SysEmpService;
import cn.stylefeng.guns.sys.modular.user.entity.SysUser;
import cn.stylefeng.guns.sys.modular.user.service.SysUserService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author 李宝嘉
 * @Date 2021/11/24 22:43
 */
@Service
public class MiniAppUserServiceImpl implements MiniAppUserService {

    private static final Log log = Log.get();
    public static final String INIT_BIt = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";

    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysEmpService sysEmpService;
    @Resource
    private AuthService authService;
    @Resource
    private UserCache userCache;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public String login(WxMaJscode2SessionResult session, String token) {
        log.debug("向微信服务器请求openid" + session.toString());
        SysUser sysUser = sysUserService.getUserByOpenId(session.getOpenid());
        this.createUser(session, sysUser);
        //已注册用户，登录携带token，token有效，刷新token
        if (ObjectUtil.isNotEmpty(token)) {
            authService.checkToken(token);
            //根据token获取JwtPayLoad部分
            JwtPayLoad jwtPayLoad = JwtTokenUtil.getJwtPayLoad(token);

            //从redis缓存中获取登录用户
            Object cacheObject = userCache.get(jwtPayLoad.getUuid());
            //转换成登录用户
            if (ObjectUtil.isNotEmpty(cacheObject)) {
                SysLoginUser sysLoginUser = (SysLoginUser) cacheObject;
                authService.cacheLoginUser(jwtPayLoad, sysLoginUser);
                this.initUserRedis(sysUser);
                return token;
            }
        }
        this.initUserRedis(sysUser);
        //注册完生成token
        return ((AuthServiceImpl) authService).doLogin(sysUser);
    }

    /**
     * 用户登录时，初始化今明两天redis缓存
     *
     * @param sysUser 用户信息
     */
    private void initUserRedis(SysUser sysUser) {
        DateTime now = DateTime.now();
        String key = "userId:" + DateUtil.format(now, "MM-dd") + sysUser.getId().toString();
        DateTime tomorrow = DateUtil.beginOfDay(DateUtil.tomorrow());
        long todayExpire = DateUtil.betweenMs(now, tomorrow);
        stringRedisTemplate.opsForValue().setIfAbsent(key, INIT_BIt, todayExpire, TimeUnit.MILLISECONDS);

        key = "userId:" + DateUtil.format(tomorrow, "MM-dd") + sysUser.getId().toString();
        long tomorrowExp = DateUtil.betweenMs(now, DateUtil.offsetDay(tomorrow, 1));
        stringRedisTemplate.opsForValue().setIfAbsent(key, INIT_BIt, tomorrowExp, TimeUnit.MILLISECONDS);
    }

    /**
     * 创建新用户
     *
     * @param session 向微信服务器换取的信息
     * @param sysUser 用户
     */
    private void createUser(WxMaJscode2SessionResult session, SysUser sysUser) {
        //第一次登录用户openid不存在，自动创建账户
        if (ObjectUtil.isEmpty(sysUser)) {
            sysUser = new SysUser();
            sysUser.setOpenId(session.getOpenid());
            sysUser.setSessionKey(session.getSessionKey());
            sysUser.setAccount("miniapp2");
            sysUser.setPassword(BCrypt.hashpw("miniappPassword", BCrypt.gensalt()));
            sysUser.setName("微信小程序2");
            sysUser.setSex(SexEnum.MAN.getCode());
            sysUser.setAdminType(AdminTypeEnum.NONE.getCode());
            sysUser.setStatus(CommonStatusEnum.ENABLE.getCode());
            sysUserService.save(sysUser);
            Long sysUserId = sysUser.getId();
            //增加员工信息
            SysEmpParam sysEmpParam = new SysEmpParam();
            sysEmpParam.setJobNum("021");
            sysEmpParam.setOrgId(1265476890672672771L);
            sysEmpParam.setOrgName("研发部");
            List<Long> posIds = new ArrayList<>();
            posIds.add(1265476890672672790L);
            sysEmpParam.setPosIdList(posIds);
            sysEmpParam.setId(sysUserId);
            sysEmpService.addOrUpdate(sysEmpParam);
            log.debug("新用户自动注册成功");
        }
    }
}
